
FakeObjMeta = {
	__ptr = "Fake",
	PushState = function () end,
	PopState = function () end,
	PushOrient = function () end,
	PopOrient = function () end,
	SetShowBounding = function () end,
	SetShowVertex = function () end,
	SetShowSelVertex = function () end,
	SetShowSelFace = function () end,
	SetShowWireframe = function () end,
	SetZEnable = function () end,
	SetAlphaBlend = function () end,
	SetCullNone = function () end,
	SetAlphaTest = function () end,
	SetCanSave = function () end,
	GetShowBounding = function () end,
	GetShowVertex = function () end,
	GetShowSelVertex = function () end,
	GetShowSelFace = function () end,
	GetShowWireframe = function () end,
	GetZEnable = function () end,
	GetAlphaBlend = function () end,
	GetCullNone = function () end,
	GetAlphaTest = function () end,
	GetCanSave = function () end,

	GetPos = function () end,
	GetMesh = function () end,
	GetName = function () end,
	GetTexture = function () end,
	GetScaling = function () end,
	SetVisible = function () end,
	SetPos = function () end,
	SetShader = function () end,
	SetMesh = function () end,
	SetName = function () end,
	SetTexture = function () end,
	SetAmbient = function () end,
	SetDiffuse = function () end,
	SetScaling = function () end,
	SetAlpha = function () end,
	RotateWorld = function () end,
	RotateWorldOffCenter = function () end,
	RotateObjRight = function () end,
	RotateObjUp = function () end,
	RotateObjLook = function () end,
	ResetOrientation = function () end,
	AddSelIndex = function () end,
	ClearSelIndex = function () end,
	CopyOrientation = function () end,
	CopyAll = function () end,
	Move = function () end,
	CalObjSpaceTransform = function () end,
	TransformToObjSpace = function () end,
	TransformToWorldSpace = function () end
}
FakeObjMeta.__index = FakeObjMeta

EditVertexFunc = function ()
	if not SelectMode.HasObj() then return end
	TRACE("EditVertexFunc - Begin.\n")
	EditWin.EditVertex:SetText("QuitEditVert")
	EditWin.EditVertex:SetOnClick(EditVertexQuitFunc)
	g_CurMode = SelectVertexMode
	ChangeMode_BackMode = SelectVertexMode
	SelectVertexMode.Begin()
end

EditVertexQuitFunc = function ()
	EditWin.EditVertex:SetText("EditVertex")
	EditWin.EditVertex:SetOnClick(EditVertexFunc)
	if g_CurMode then g_CurMode.FuncSeq.End() end
	SelectVertexMode.End()
	g_CurMode = nil
	ChangeMode_BackMode = nil
	TRACE("EditVertexQuitFunc - End.\n")
end

EditFaceFunc = function ()
	if not SelectMode.HasObj() then return end
	TRACE("EditFaceFunc - Begin.\n")
	EditWin.EditFace:SetText("QuitEditFace")
	EditWin.EditFace:SetOnClick(EditFaceQuitFunc)
	g_CurMode = SelectFaceMode
	ChangeMode_BackMode = SelectFaceMode
	SelectFaceMode.Begin()
end

EditFaceQuitFunc = function ()
	EditWin.EditFace:SetText("EditFace")
	EditWin.EditFace:SetOnClick(EditFaceFunc)
	SelectFaceMode.End()
	if g_CurMode then g_CurMode.FuncSeq.End() end
	g_CurMode = nil
	ChangeMode_BackMode = nil
	TRACE("EditFaceQuitFunc - End.\n")
end

function MakeFakeObj(EditObj,tIndex)
	local MeshName = EditObj:GetMesh()
	local Mesh = g_MgrMesh:Find(MeshName)
	if not Mesh then return end

	local FakeObj = {}
	FakeObj.BelongObj = EditObj
	FakeObj.tIndex = tIndex
	FakeObj.Vertices = Mesh:TransformIndexToVertexUnique(tIndex)
	setmetatable(FakeObj,FakeObjMeta)

	function FakeObj:GetPos ()
		Mesh:LockVertex()
		local vPosSum = {x=0,y=0,z=0}
		for _,v in ipairs(FakeObj.Vertices) do
			local vPos = Mesh:GetPos(v)
			Vector.Add(vPosSum,vPos)
		end
		local t = 1.0/table.getn(FakeObj.Vertices)
		Vector.Coef(vPosSum,t)
		EditObj:CalObjSpaceTransform()
		vPosSum = EditObj:TransformToWorldSpace(vPosSum)

		Mesh:UnlockVertex()
		return vPosSum
	end
	function FakeObj:Move(PosBias)
		Mesh:LockVertex()
		for _,v in ipairs(FakeObj.Vertices) do
			Mesh:Move(v,PosBias)
		end
		Mesh:UnlockVertex()
	end
	function FakeObj:SetPos (vPos)
		local OldPos = FakeObj.GetPos()
		local PosBias = {x=vPos.x-OldPos.x,y=vPos.y-OldPos.y,z=vPos.z-OldPos.z}
		Mesh:LockVertex()
		for _,v in ipairs(FakeObj.Vertices) do
			Mesh:Move(v,PosBias)
		end
		Mesh:UnlockVertex()
	end
	function FakeObj:GetScaling ()
		return {x=1,y=1,z=1}
	end
	function FakeObj:SetScaling(Scaling)
		local CenterPos = FakeObj.GetPos()
		Vector.Subtract(Scaling,{x=1,y=1,z=1})
		EditObj:CalObjSpaceTransform()
		Mesh:LockVertex()
		for _,v in ipairs(FakeObj.Vertices) do
			local CurDir = Mesh:GetPos(v)
			CurDir = EditObj:TransformToWorldSpace(CurDir)
			Vector.Subtract(CurDir,CenterPos)
			Vector.Normalize(CurDir)
			CurDir.x, CurDir.y, CurDir.z = CurDir.x*Scaling.x, CurDir.y*Scaling.y, CurDir.z*Scaling.z
			Mesh:Move(v,CurDir)
		end
		Mesh:UnlockVertex()
	end
	function FakeObj:RotateWorld(x,y,z)
		local colx = {x=1,y=0,z=0}
		local coly = {x=0,y=1,z=0}
		local colz = {x=0,y=0,z=1}
		if x~=0 then
			colx.x,coly.x,colz.x = 1, 0, 0
			colx.y,coly.y,colz.y = 0, math.cos(x), -math.sin(x)
			colx.z,coly.z,colz.z = 0, math.sin(x), math.cos(x)
		elseif y~=0 then
			colx.x,coly.x,colz.x = math.cos(y), 0, -math.sin(y)
			colx.y,coly.y,colz.y = 0, 1, 0
			colx.z,coly.z,colz.z = math.sin(y), 0, math.cos(y)
		elseif z~=0 then
			colx.x,coly.x,colz.x = math.cos(z), -math.sin(z), 0
			colx.y,coly.y,colz.y = math.sin(z), math.cos(z), 0
			colx.z,coly.z,colz.z = 0, 0, 1
		else
			return
		end
		local CenterPos = FakeObj.GetPos()
		EditObj:CalObjSpaceTransform()
		Mesh:LockVertex()
		for _,v in ipairs(FakeObj.Vertices) do
			local CurPos = Mesh:GetPos(v)
			CurPos = EditObj:TransformToWorldSpace(CurPos)
			Vector.Subtract(CurPos,CenterPos)
			--Transform
			CurPos.x, CurPos.y, CurPos.z =
			colx.x*CurPos.x+coly.x*CurPos.y+colz.x*CurPos.z,
			colx.y*CurPos.x+coly.y*CurPos.y+colz.y*CurPos.z,
			colx.z*CurPos.x+coly.z*CurPos.y+colz.z*CurPos.z

			Vector.Add(CurPos,CenterPos)
			CurPos = EditObj:TransformToObjSpace(CurPos)
			Mesh:SetPos(v,CurPos)
		end
		Mesh:UnlockVertex()
	end
	function FakeObj:GetTexture()
		return FakeObj.BelongObj:GetTexture()
	end

	return FakeObj
end

SelectVertexMode = {
	Begin = function ()
		SelectVertexMode.CurFuncSeq = SelectVertexMode.FuncSeq.Pass1
		local EditObj = SelectMode.PickObjs[1]
		EditObj:SetShowVertex(true)
		EditObj:SetShowSelVertex(true)
		SelectVertexMode.EditObj = EditObj
	end,
	End = function ()
		local EditObj = SelectVertexMode.EditObj
		EditObj:SetShowVertex(false)
		EditObj:SetShowSelVertex(false)
		if SelectVertexMode.EditObj then
			SelectVertexMode.EditObj:ClearSelIndex()
		end
		SelectVertexMode.EditObj = nil
		SelectMode.ClearObj()
	end,
	FuncSeq = {
		Pass1 = function ()
			if SelectMode.HasObj() then
				--if mesh is used by other objs, then make a copy of it

				--go to pass2
				SelectVertexMode.CurFuncSeq = SelectVertexMode.FuncSeq.Pass2
			end
		end,
		Pass2 = function ()
			--selvertex

			local EditObj = SelectVertexMode.EditObj
			if not EditObj then return end
			MarqueeMode.CurFuncSeq()

			TexcoordMode.EditObj = SelectVertexMode.FakeObj

			if MarqueeMode.Stop then return end

			local MultiSelect = false
			if cWindow:KeyDown(DIK.LCONTROL) then MultiSelect = true end
			if MultiSelect and not EditObj.SelVertex then
				EditObj.SelVertex={}
				if SelectVertexMode.tIndex then
					for _,v in ipairs(SelectVertexMode.tIndex) do EditObj.SelVertex[v] = true end
				end
			end

			local tIndex = EditObj:IntersectVertexRect(MarqueeMode.MouseCoordStart,MarqueeMode.MouseCoordEnd,g_Camera)
			if not tIndex then
				SelectVertexMode.FakeObj = nil
				if not MultiSelect then
					EditObj:ClearSelIndex()
					EditObj.SelVertex = nil
				end
				return
			end

			if not MultiSelect then
				EditObj:ClearSelIndex()
				EditObj.SelVertex = nil
				SelectVertexMode.tIndex = tIndex
			else
				if SelectVertexMode.tIndex then
					for _,v in ipairs(tIndex) do
						if not EditObj.SelVertex[v] then
							table.insert(SelectVertexMode.tIndex,v)
						end
					end
				else
					SelectVertexMode.tIndex = tIndex
				end
			end
			for k,v in ipairs(tIndex) do
				--TRACE(string.format("%d ",v))
				EditObj:AddSelIndex(v)
				if MultiSelect then EditObj.SelVertex[v] = true end
			end

			local FakeObj = MakeFakeObj(EditObj,SelectVertexMode.tIndex)
			TRACE(string.format("SelectVertexMode - Num Of Vertices in Marquee: %d\n",table.getn(FakeObj.Vertices)))

			SelectMode.ClearObj()
			SelectMode.AddObj(FakeObj)

			SelectVertexMode.FakeObj = FakeObj
			TexcoordMode.EditObj = FakeObj
		end,
		End = function ()
		end
	}
}
local EditFacePop
SelectFaceMode = {
	Begin = function ()
		SelectFaceMode.CurFuncSeq = SelectFaceMode.FuncSeq.Pass1

		EditFacePop = cDXUIWindow:New()	
		cWindow:AddDXUI(EditFacePop)
		EditFacePop:SetTitle("EditFacePop")
		EditFacePop:NoCloseButton()
		EditFacePop:SetPos(750,300)
		EditFacePop:SetSize(250,100)

		local EditObj = SelectMode.PickObjs[1]
		EditObj:SetShowVertex(false)
		EditObj:SetShowWireframe(true)
		EditObj:SetShowSelFace(true)
		SelectFaceMode.EditObj = EditObj
	end,
	End = function ()
		EditFacePop:Close()

		local EditObj = SelectFaceMode.EditObj
		EditObj:SetShowWireframe(false)
		EditObj:SetShowSelFace(false)
		if SelectFaceMode.EditObj then
			SelectFaceMode.EditObj:ClearSelIndex()
		end
		SelectFaceMode.EditObj = nil
		SelectMode.ClearObj()
	end,
	FuncSeq = {
		Pass1 = function ()
			--prepare & check
			SelectFaceMode.CurFuncSeq = SelectFaceMode.FuncSeq.Pass2
		end,
		Pass2 = function ()
			local EditObj = SelectFaceMode.EditObj
			if not EditObj then return end
			MarqueeMode.CurFuncSeq()

			TexcoordMode.EditObj = SelectFaceMode.FakeObj
			FreeTexMode.EditObj = SelectFaceMode.FakeObj

			if MarqueeMode.Stop then return end

			local MultiSelect = false
			if cWindow:KeyDown(DIK.LCONTROL) then MultiSelect=true end
			if MultiSelect and not EditObj.SelFace then
				EditObj.SelFace={}
				if SelectFaceMode.tIndex then
					for _,v in ipairs(SelectFaceMode.tIndex) do EditObj.SelFace[v] = true end
				end
			end

			local tIndex = EditObj:IntersectFaceRect(MarqueeMode.MouseCoordStart,MarqueeMode.MouseCoordEnd,g_Camera)
			if not tIndex then
				SelectFaceMode.FakeObj = nil
				if not MultiSelect then
					EditObj:ClearSelIndex()
					EditObj.SelFace = nil
				end
				return
			end

			if not MultiSelect then
				EditObj:ClearSelIndex()
				EditObj.SelFace = nil
				SelectFaceMode.tIndex = tIndex
			else
				if SelectFaceMode.tIndex then
					for _,v in ipairs(tIndex) do
						if not EditObj.SelFace[v] then
							table.insert(SelectFaceMode.tIndex,v)
						end
					end
				else
					SelectFaceMode.tIndex = tIndex
				end
			end
			TRACE(string.format("SelectFaceMode - Num Of Faces in Marquee: %d\n",table.getn(SelectFaceMode.tIndex)/3)) 
			local str = string.format("Num Of Faces: %d\n",table.getn(SelectFaceMode.tIndex)/3) 
			EditFacePop:SetText(str)

			for k,v in ipairs(tIndex) do
				--TRACE(string.format("%d ",v))
				EditObj:AddSelIndex(v)
				if MultiSelect then EditObj.SelFace[v] = true end
			end

			local FakeObj = MakeFakeObj(EditObj,SelectFaceMode.tIndex)

			SelectFaceMode.FakeObj = FakeObj
			TexcoordMode.EditObj = FakeObj
			FreeTexMode.EditObj = FakeObj
			SelectMode.ClearObj()
			SelectMode.AddObj(FakeObj)
		end,
		End = function ()
		end
	}
}
